home *** CD-ROM | disk | FTP | other *** search
/ Aminet 25 / Aminet 25 (1998)(GTI - Schatztruhe)[!][Jun 1998].iso / Aminet / misc / emu / atari800_tr.lzh / atari.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-02-17  |  15.0 KB  |  716 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5. #include <signal.h>
  6. #include <sys/time.h>
  7. #include <unistd.h>
  8.  
  9. #ifdef VMS
  10. #include <unixio.h>
  11. #include <file.h>
  12. #else
  13. #include <fcntl.h>
  14. #endif
  15.  
  16. #ifdef DJGPP
  17. #include "djgpp.h"
  18. #endif
  19.  
  20. static char *rcsid = "$Id: atari.c,v 1.60 1998/02/17 thor,david Exp $";
  21.  
  22. #define FALSE   0
  23. #define TRUE    1
  24.  
  25. #include "atari.h"
  26. #include "cpu.h"
  27. #include "mem.h"
  28. #include "antic.h"
  29. #include "gtia.h"
  30. #include "pia.h"
  31. #include "pokey.h"
  32. #include "pokey11.h"
  33. #include "supercart.h"
  34. #include "devices.h"
  35. #include "sio.h"
  36. #include "monitor.h"
  37. #include "platform.h"
  38. #include "prompts.h"
  39. #include "rt-config.h"
  40. #include "ui.h"
  41. #include "patch.h"
  42.  
  43. TVmode tv_mode = PAL;
  44. Machine machine = Atari;
  45. int verbose = FALSE;
  46.  
  47. static void Atari800_Hardware (void);
  48.  
  49. int load_cart (char *filename, int type);
  50.  
  51. void sigint_handler (int num)
  52. {
  53.   Atari800_Exit (TRUE, 0);
  54.  
  55.   signal (SIGINT, sigint_handler);
  56.   return;
  57. }
  58.  
  59.  
  60. void InitHW(int *argc,char **argv)
  61. {
  62.   SetBlank(0xd000,0xd7ff);
  63.   Init_PIA(argc,argv,0xd300);
  64.   Init_Pokey(argc,argv,0xd200);
  65.   Init_GTIA(argc,argv,0xd000);
  66.   Init_Antic(argc,argv,0xd400);
  67.   Init_Super(argc,argv,0xd500);
  68. }
  69.  
  70. void Init5200HW(int *argc,char **argv)
  71. {
  72.   SetBlank(0xc000,0xf7ff);
  73.   Init_GTIA(argc,argv,0xc000);     /* 5200 GTIA chip */
  74.   Init_Antic(argc,argv,0xd400);
  75.   Init_Pokey(argc,argv,0xe800);
  76.   Init_Pokey(argc,argv,0xeb00);
  77.   EnableOs();
  78. }
  79.  
  80. void HW_Reset(void)
  81. {
  82.  
  83.   if (machine==Atari5200)
  84.     Init5200HW(NULL,NULL);
  85.   else
  86.     InitHW(NULL,NULL);
  87. }
  88.  
  89.  
  90.  
  91. /*
  92.  * This removes any loaded cartridge ROM files from the emulator
  93.  * It doesn't remove either the OS, FFP or character set ROMS.
  94.  */
  95.  
  96. int Remove_ROM (void)
  97. {
  98.   RemoveCurrent();
  99.   return TRUE;
  100. }
  101.  
  102. #define STD_8K 1
  103. #define STD_16K 2
  104. #define OSS 3
  105. #define AGS 4
  106. #define AGS_16 5
  107.  
  108. int Insert_Cartridge (char *filename)
  109. {
  110.   int status = FALSE;
  111.   int fd;
  112.  
  113.   fd = open (filename, O_RDONLY, 0777);
  114.   if (fd != -1)
  115.     {
  116.       UBYTE header[16];
  117.  
  118.       read (fd, header, sizeof(header));
  119.       if ((header[0] == 'C') &&
  120.           (header[1] == 'A') &&
  121.           (header[2] == 'R') &&
  122.           (header[3] == 'T'))
  123.         {
  124.           int type;
  125.           int checksum;
  126.  
  127.           type = (header[4] << 24) |
  128.                  (header[5] << 16) |
  129.                  (header[6] << 8) |
  130.                  header[7];
  131.  
  132.           checksum = (header[4] << 24) |
  133.                      (header[5] << 16) |
  134.                      (header[6] << 8) |
  135.                      header[7];
  136.  
  137.           switch (type)
  138.             {
  139.              case STD_8K :
  140.         status = Insert_8K_ROM (NULL,fd);
  141.                 break;
  142.               case STD_16K :
  143.         status = Insert_16K_ROM (NULL,fd);
  144.                 break;
  145.               case OSS :
  146.         status = Insert_OSS_ROM (NULL,fd);
  147.                 break;
  148.               case AGS :
  149.         status = Insert_32K_5200ROM(NULL,fd);
  150.                 break;
  151.           case AGS_16:
  152.         status = Insert_16K_5200ROM(NULL,fd);
  153.         break;
  154.               default :
  155.                 printf ("%s is in unsupported cartridge format %d\n",
  156.                         filename, type);
  157.                 break;
  158.             }
  159.         }
  160.       else
  161.         {
  162.           printf ("%s is not a cartridge\n", filename);
  163.         }
  164.       close (fd);
  165.     }
  166.  
  167.   return status;
  168. }
  169.  
  170. void Coldstart (void)
  171. {
  172.  
  173.   HW_Reset ();
  174.   Poke(0x244,1);
  175.   Poke(0x9,0);
  176.   Poke(0x33d,0);
  177.   Poke(0x33e,0);
  178.   Poke(0x33f,0);
  179.   CPU_Reset ();
  180.  
  181.   if (hold_option)
  182.     next_console_value = 0x03; /* Hold Option During Reboot */
  183.  
  184. }
  185.  
  186. void Warmstart (void)
  187. {
  188.   HW_Reset ();
  189.   CPU_Reset ();
  190. }
  191.  
  192. int Initialise_AtariOSA (int *argc,char **argv)
  193. {
  194. int status;
  195.  
  196.   FreeCarts();
  197.   if ((status = ReadOSABRom(atari_osa_filename,0))!=0) {
  198.     machine = Atari;
  199.     PatchOsA ();
  200.     SetRAM (0x0000, 0xbfff);
  201.     if (enable_c000_ram)
  202.       SetRAM (0xc000, 0xcfff);
  203.     else
  204.       SetROM (0xc000, 0xcfff);
  205.     SetROM (0xd800, 0xffff);
  206.     InitHW(argc,argv);
  207.     Coldstart ();
  208.   }
  209.  
  210.   return status;
  211. }
  212.  
  213. int Initialise_AtariOSB (int *argc,char **argv)
  214. {
  215. int status;
  216.  
  217.   FreeCarts();
  218.   if ((status = ReadOSABRom(atari_osb_filename,0))!=0) {
  219.       machine = Atari;
  220.       PatchOsB ();
  221.       SetRAM (0x0000, 0xbfff);
  222.       if (enable_c000_ram)
  223.     SetRAM (0xc000, 0xcfff);
  224.       else
  225.     SetROM (0xc000, 0xcfff);
  226.       SetROM (0xd800, 0xffff);
  227.       InitHW(argc,argv);
  228.       Coldstart ();
  229.     }
  230.  
  231.   return status;
  232. }
  233.  
  234. int Initialise_AtariXL (int *argc,char **argv)
  235. {
  236. int status;
  237.  
  238.   FreeCarts();
  239.   if ((status = ReadXLRom(atari_xlxe_filename,0))!=0) {
  240.       machine = AtariXL;
  241.       PatchOsXL ();
  242.       SetRAM (0x0000,0xbfff);
  243.       status = ReadBasic(atari_basic_filename,0);
  244.       InitHW(argc,argv);     
  245.       Coldstart ();
  246.     }
  247.  
  248.   return status;
  249. }
  250.  
  251. int Initialise_AtariXE (int *argc,char **argv)
  252. {
  253. int status;
  254.  
  255.   FreeCarts();
  256.   if ((status = Build_XE_Banks())!=0) {
  257.     status = Initialise_AtariXL (argc,argv);
  258.     machine = AtariXE;
  259.   }
  260.   return status;
  261. }
  262.  
  263. int Initialise_Atari5200 (int *argc,char **argv)
  264. {
  265. int status;
  266.  
  267.   FreeCarts();
  268.   if ((status = Read5200Rom (atari_5200_filename,0))!=0) {
  269.       machine = Atari5200;
  270.       SetRAM (0x0000, 0x3fff);
  271.       SetROM (0x4000, 0xffff);
  272.       Init5200HW (argc,argv);  /* This call installes the hardware */
  273.       Coldstart ();
  274.     }
  275.  
  276.   return status;
  277. }
  278.  
  279. int main (int argc, char *argv[])
  280. {
  281. int status = FALSE;
  282. int error;
  283. int diskno = 1;
  284. int i;
  285. int j;
  286. char *rom_filename = NULL;
  287. int cart_type = CARTRIDGE;
  288. int os = 1;
  289.  
  290.   char *rtconfig_filename = NULL;
  291.   int config = FALSE;
  292.  
  293.   error = FALSE;
  294.  
  295.   for (i=j=1;i<argc;i++)
  296.     {
  297.       if (strcmp(argv[i],"-configure") == 0)
  298.         config = TRUE;
  299.       else if (strcmp(argv[i],"-config") == 0)
  300.         rtconfig_filename = argv[++i];
  301.       else if (strcmp(argv[i],"-v") == 0)
  302.     {
  303.       printf ("%s\n", ATARI_TITLE);
  304.       exit (1);
  305.     }
  306.       else if (strcmp(argv[i],"-verbose") == 0)
  307.         verbose = TRUE;
  308.       else
  309.     argv[j++] = argv[i];
  310.     }
  311.  
  312.   argc = j;
  313.  
  314.   if (!RtConfigLoad (rtconfig_filename))
  315.     config = TRUE;
  316.  
  317.   if (config)
  318.     {
  319.       RtConfigUpdate ();
  320.       RtConfigSave ();
  321.     }
  322.  
  323.   switch (default_system)
  324.     {
  325.       case 1 :
  326.         machine = Atari;
  327.         os = 1;
  328.         break;
  329.       case 2 :
  330.         machine = Atari;
  331.         os = 2;
  332.         break;
  333.       case 3 :
  334.         machine = AtariXL;
  335.         break;
  336.       case 4 :
  337.         machine = AtariXE;
  338.         break;
  339.       case 5 :
  340.         machine = Atari5200;
  341.         break;
  342.       default :
  343.         machine = AtariXL;
  344.         break;
  345.      } 
  346.  
  347.   switch (default_tv_mode)
  348.     {
  349.       case 1 :
  350.       default :
  351.         tv_mode = PAL;
  352.         break;
  353.       case 2 :
  354.         tv_mode = NTSC;
  355.         break;
  356.     }
  357.  
  358.   for (i=j=1;i<argc;i++)
  359.     {
  360.       if (strcmp(argv[i],"-atari") == 0)
  361.     machine = Atari;
  362.       else if (strcmp(argv[i],"-xl") == 0)
  363.     machine = AtariXL;
  364.       else if (strcmp(argv[i],"-xe") == 0)
  365.     machine = AtariXE;
  366.       else if (strcmp(argv[i],"-5200") == 0)
  367.     machine = Atari5200;
  368.       else if (strcmp(argv[i],"-nobasic") == 0)
  369.         hold_option = TRUE;
  370.       else if (strcmp(argv[i],"-nopatch") == 0)
  371.     enable_sio_patch = FALSE;
  372.       else if (strcmp(argv[i],"-pal") == 0)
  373.     tv_mode = PAL;
  374.       else if (strcmp(argv[i],"-ntsc") == 0)
  375.     tv_mode = NTSC;
  376.       else if (strcmp(argv[i],"-osa_rom") == 0)
  377.         strcpy (atari_osa_filename, argv[++i]);
  378.       else if (strcmp(argv[i],"-osb_rom") == 0)
  379.         strcpy (atari_osb_filename, argv[++i]);
  380.       else if (strcmp(argv[i],"-xlxe_rom") == 0)
  381.         strcpy (atari_xlxe_filename, argv[++i]);
  382.       else if (strcmp(argv[i],"-5200_rom") == 0)
  383.         strcpy (atari_5200_filename, argv[++i]);
  384.       else if (strcmp(argv[i],"-basic_rom") == 0)
  385.         strcpy (atari_basic_filename, argv[++i]);
  386.       else if (strcmp(argv[i],"-cart") == 0)
  387.         {
  388.       rom_filename = argv[++i];
  389.       cart_type = CARTRIDGE;
  390.         }
  391.       else if (strcmp(argv[i],"-rom") == 0)
  392.     {
  393.       rom_filename = argv[++i];
  394.       cart_type = NORMAL8_CART;
  395.     }
  396.       else if (strcmp(argv[i],"-rom16") == 0)
  397.     {
  398.       rom_filename = argv[++i];
  399.       cart_type = NORMAL16_CART;
  400.     }
  401.       else if (strcmp(argv[i],"-ags32") == 0)   /* 5200 32K rom */
  402.     {
  403.       rom_filename = argv[++i];
  404.       cart_type = AGS32_CART;
  405.     }
  406.       else if (strcmp(argv[i],"-ags16") == 0)   /* 5200 16K rom */
  407.     {
  408.       rom_filename = argv[++i];
  409.       cart_type = AGS16_CART;
  410.     }
  411.       else if (strcmp(argv[i],"-oss") == 0)
  412.     {
  413.       rom_filename = argv[++i];
  414.       cart_type = OSS_SUPERCART;
  415.     }
  416.       else if (strcmp(argv[i],"-db") == 0)    /* db 16/32 superduper cart */
  417.     {
  418.       rom_filename = argv[++i];
  419.       cart_type = DB_SUPERCART;
  420.     }
  421.       else if (strcmp(argv[i],"-refresh") == 0)
  422.     {
  423.       sscanf (argv[++i],"%d", &refresh_rate);
  424.       if (refresh_rate < 1)
  425.         refresh_rate = 1;
  426.     }
  427.       else if (strcmp(argv[i],"-maxmiss") == 0)
  428.     {
  429.       sscanf (argv[++i],"%d", &maxmiss);
  430.       if (maxmiss < 0)
  431.         maxmiss = 0;
  432.     }
  433.       else if (strcmp(argv[i],"-help") == 0)
  434.     {
  435.           printf ("\t-configure    Update Configuration File\n"
  436.                   "\t-config fnm   Specify Alternate Configuration File\n"
  437.                   "\t-atari        Standard Atari 800 mode\n"
  438.                   "\t-xl           Atari XL mode\n"
  439.                   "\t-xe           Atari XE mode (Currently same as -xl)\n"
  440.                   "\t-5200         Atari 5200 Games System\n"
  441.                   "\t-pal          Enable PAL TV mode\n"
  442.                   "\t-ntsc         Enable NTSC TV mode\n"
  443.                   "\t-rom fnm      Install standard 8K Cartridge\n"
  444.               "\t-rom16 fnm    Install standard 16K Cartridge\n"
  445.           "\t-ags32 fnm    Install 5200/AGS 32K Cartridge\n"
  446.           "\t-ags16 fnm    Install 5200/AGS 16K Cartridge\n"
  447.               "\t-oss fnm      Install OSS Super Cartridge\n"
  448.               "\t-db fnm       Install DB's 16/32K Cartridge (not for normal use)\n"
  449.               "\t-refresh num  Specify screen refresh rate\n"
  450.               "\t-maxmiss num  Specify maximal number of missing frames\n"
  451.           "\t-artefacts    Generate artefacts for half color clock graphics\n"
  452.               "\t-nopatch      Don't patch SIO routine in OS\n"
  453.               "\t-a            Use A OS\n"
  454.               "\t-b            Use B OS\n"
  455.                   "\t-c            Enable RAM between 0xc000 and 0xd000\n"
  456.               "\t-v            Show version/release number\n");
  457.       argv[j++] = argv[i];
  458.     }
  459.       else if (strcmp(argv[i],"-a") == 0)
  460.     os = 1;
  461.       else if (strcmp(argv[i],"-b") == 0)
  462.     os = 2;
  463.       else if (strcmp(argv[i],"-c") == 0)
  464.     enable_c000_ram = TRUE;
  465.       else
  466.     argv[j++] = argv[i];
  467.     }
  468.  
  469.   argc = j;
  470.  
  471.   Device_Initialise (&argc, argv);
  472.   SIO_Initialise (&argc, argv);
  473.  
  474.   Atari_Initialise (&argc, argv); /* Platform Specific Initialisation */
  475.  
  476.   if (!atari_screen)
  477.     {
  478.       atari_screen = (ULONG*)malloc((ATARI_HEIGHT+16) * ATARI_MODULO);
  479.       for (i=0;i<256;i++)
  480.     colour_translation_table[i] = i;
  481.     }
  482.  
  483.   /*
  484.    * Configure Atari System
  485.    */
  486.  
  487.   switch (machine)
  488.     {
  489.     case Atari :
  490.       if (os == 1)
  491.     status = Initialise_AtariOSA (&argc,argv);
  492.       else
  493.     status = Initialise_AtariOSB (&argc,argv);
  494.       break;
  495.     case AtariXL :
  496.       status = Initialise_AtariXL (&argc,argv);
  497.       break;
  498.     case AtariXE :
  499.       status = Initialise_AtariXE (&argc,argv);
  500.       break;
  501.     case Atari5200 :
  502.       status = Initialise_Atari5200 (&argc,argv);
  503.       break;
  504.     default :
  505.       printf ("Fatal Error in atari.c\n");
  506.       Atari800_Exit (FALSE, 1);
  507.     }
  508.  
  509.   /*
  510.    * Any parameters left on the command line must be disk images.
  511.    */
  512.  
  513.   for (i=1;i<argc;i++)
  514.     {
  515.       if (!SIO_Mount (diskno++, argv[i]))
  516.     {
  517.       printf ("Disk File %s not found\n", argv[i]);
  518.       error = TRUE;
  519.     }
  520.     }
  521.  
  522.   if (error)
  523.     {
  524.       printf ("Usage: %s [-rom filename] [-oss filename] [diskfile1...diskfile8]\n", argv[0]);
  525.       printf ("\t-help         Extended Help\n");
  526.       Atari800_Exit (FALSE, 1);
  527.     }
  528.  
  529.   /*
  530.    * Install CTRL-C Handler
  531.    */
  532.  
  533.   signal (SIGINT, sigint_handler);
  534.  
  535.   if (!status)
  536.     {
  537.       printf ("Operating System not available\n");
  538.       Atari800_Exit (FALSE, 1);
  539.     }
  540. /*
  541.  * ================================
  542.  * Install requested ROM cartridges
  543.  * ================================
  544.  */
  545.   if (rom_filename)
  546.     {
  547.       switch (cart_type)
  548.     {
  549.         case CARTRIDGE :
  550.           status = Insert_Cartridge (rom_filename);
  551.           break;
  552.     case OSS_SUPERCART :
  553.       status = Insert_OSS_ROM (rom_filename,0);
  554.       break;
  555.     case DB_SUPERCART :
  556.       status = Insert_DB_ROM (rom_filename,0);
  557.       break;
  558.     case NORMAL8_CART :
  559.       status = Insert_8K_ROM (rom_filename,0);
  560.       break;
  561.     case NORMAL16_CART :
  562.       status = Insert_16K_ROM (rom_filename,0);
  563.       break;
  564.     case AGS32_CART :
  565.       status = Insert_32K_5200ROM (rom_filename,0);
  566.       break;
  567.     case AGS16_CART :
  568.       status = Insert_16K_5200ROM (rom_filename,0);
  569.       break;
  570.     }
  571.     }
  572.  
  573. /*
  574.  * ======================================
  575.  * Reset CPU and start hardware emulation
  576.  * ======================================
  577.  */
  578.  
  579.   Atari800_Hardware ();
  580.   printf("Fatal error: Atari800_Hardware() returned\n");
  581.   Atari800_Exit(FALSE, 1);
  582.   return 1;
  583. }
  584.  
  585. /* This is now the global exit routine.
  586.     run_monitor = TRUE : run the monitor, exit only if QUIT was chosen
  587.     exitcode :  The global return
  588.    Note that the function only returns if run_monitor=TRUE and "CONT" was
  589.    given.  Return will be 1. */
  590. int Atari800_Exit (int run_monitor, int exitcode)
  591. {
  592.  
  593.   int ret=Atari_Exit (run_monitor);
  594.  
  595.   if (!ret)
  596.     {
  597.       int diskno;
  598.  
  599.     for (diskno=1;diskno<8;diskno++)
  600.         SIO_Dismount (diskno);
  601.  
  602.     FreeCarts();
  603.     Free_XE_Banks();
  604.     exit(exitcode);
  605.     }
  606.  
  607.   return ret;
  608. }
  609.  
  610.  
  611. /* Get the time as number of micros */
  612. #ifndef DJGPP
  613. unsigned long PreciseTime(void)
  614. {      
  615. static struct timeval tp;
  616. static struct timezone tzp;
  617.  
  618.   gettimeofday (&tp, &tzp);
  619.   /* printf("%d,%d\n",tp.tv_sec,tp.tv_usec); */
  620.   return (tp.tv_sec * 1000000) + tp.tv_usec;
  621. }
  622. #else
  623. unsigned long PreciseTime(void)
  624. {
  625. // for dos, count ticks and use the ticks_per_second global variable
  626. // Use the high speed clock tick function uclock()
  627. uclock_t curtime;
  628. unsigned int time;
  629.  
  630.   curtime = uclock();
  631.   time = (unsigned long) curtime;
  632.   time *= 1000000/UCLOCKS_PER_SEC;
  633.   
  634.   return time;
  635. }
  636. #endif
  637.  
  638.  
  639. void Atari800_Hardware (void)
  640. {
  641. int            pil_on = FALSE;
  642. ULONG           scanrate=1000000/60;
  643. ULONG           lasttime=0;
  644. ULONG           thistime=0;
  645. int             keycode;
  646. int             unref_cnt = 0;
  647.  
  648.   if (tv_mode == PAL)
  649.     scanrate = 1000000/50;
  650.  
  651.    scanrate *= refresh_rate;
  652.  
  653.   while (TRUE)
  654.     {
  655. #ifndef BASIC
  656. /*
  657.       colour_lookup[8] = colour_translation_table[COLBK];
  658. */
  659.  
  660.       keycode = Atari_Keyboard ();
  661.  
  662.       switch (keycode)
  663.     {
  664.     case AKEY_COLDSTART :
  665.       Coldstart ();
  666.       break;
  667.     case AKEY_WARMSTART :
  668.       Warmstart ();
  669.       break;
  670.     case AKEY_EXIT :
  671.       Atari800_Exit (FALSE, 1);
  672.       break;
  673.     case AKEY_BREAK :
  674.       SendBRK();
  675.       break;
  676.         case AKEY_UI :
  677.           ui ((UBYTE *)atari_screen);
  678.           break;
  679.     case AKEY_PIL :
  680.       if (pil_on)
  681.         {
  682.           SetRAM (0x8000, 0xbfff);
  683.           pil_on = FALSE;
  684.         }
  685.       else
  686.         {
  687.           SetROM (0x8000, 0xbfff);
  688.           pil_on = TRUE;
  689.         }
  690.       break;
  691.     case AKEY_NONE :
  692.       break;
  693.     default :
  694.       SendKey(keycode);
  695.       break;
  696.     }
  697. #endif
  698.  
  699.       /*
  700.        * Generate Screen
  701.        */
  702.  
  703.       ANTIC_RunDisplayList();
  704.       thistime=PreciseTime();
  705.       /* printf("%lu,%lu,%lu\n",thistime,lasttime,lasttime+scanrate); */
  706.       if (unref_cnt>=maxmiss || thistime<=lasttime+scanrate) {
  707.     Atari_DisplayScreen ((UBYTE*)atari_screen);
  708.     unref_cnt = 0;
  709.       } else {
  710.     unref_cnt++;
  711.       }
  712.       lasttime=thistime;
  713.     }
  714. }
  715.  
  716.